﻿namespace Iesi.Collections
{
    using System;
    using System.Collections;

    [Serializable]
    public sealed class ImmutableSet : Set
    {
        private const string ERROR_MESSAGE = "Object is immutable.";
        private ISet mBasisSet;

        public ImmutableSet(ISet basisSet)
        {
            this.mBasisSet = basisSet;
        }

        public sealed override bool Add(object o)
        {
            throw new NotSupportedException("Object is immutable.");
        }

        public sealed override bool AddAll(ICollection c)
        {
            throw new NotSupportedException("Object is immutable.");
        }

        public sealed override void Clear()
        {
            throw new NotSupportedException("Object is immutable.");
        }

        public sealed override object Clone()
        {
            return new ImmutableSet(this.mBasisSet);
        }

        public sealed override bool Contains(object o)
        {
            return this.mBasisSet.Contains(o);
        }

        public sealed override bool ContainsAll(ICollection c)
        {
            return this.mBasisSet.ContainsAll(c);
        }

        public sealed override void CopyTo(Array array, int index)
        {
            this.mBasisSet.CopyTo(array, index);
        }

        public sealed override ISet ExclusiveOr(ISet a)
        {
            ISet basisSet = this;
            while (basisSet is ImmutableSet)
            {
                basisSet = ((ImmutableSet) basisSet).BasisSet;
            }
            return new ImmutableSet(basisSet.ExclusiveOr(a));
        }

        public sealed override IEnumerator GetEnumerator()
        {
            return this.mBasisSet.GetEnumerator();
        }

        public sealed override ISet Intersect(ISet a)
        {
            ISet basisSet = this;
            while (basisSet is ImmutableSet)
            {
                basisSet = ((ImmutableSet) basisSet).BasisSet;
            }
            return new ImmutableSet(basisSet.Intersect(a));
        }

        public sealed override ISet Minus(ISet a)
        {
            ISet basisSet = this;
            while (basisSet is ImmutableSet)
            {
                basisSet = ((ImmutableSet) basisSet).BasisSet;
            }
            return new ImmutableSet(basisSet.Minus(a));
        }

        public sealed override bool Remove(object o)
        {
            throw new NotSupportedException("Object is immutable.");
        }

        public sealed override bool RemoveAll(ICollection c)
        {
            throw new NotSupportedException("Object is immutable.");
        }

        public sealed override bool RetainAll(ICollection c)
        {
            throw new NotSupportedException("Object is immutable.");
        }

        public sealed override ISet Union(ISet a)
        {
            ISet basisSet = this;
            while (basisSet is ImmutableSet)
            {
                basisSet = ((ImmutableSet) basisSet).BasisSet;
            }
            return new ImmutableSet(basisSet.Union(a));
        }

        internal ISet BasisSet
        {
            get
            {
                return this.mBasisSet;
            }
        }

        public sealed override int Count
        {
            get
            {
                return this.mBasisSet.Count;
            }
        }

        public sealed override bool IsEmpty
        {
            get
            {
                return this.mBasisSet.IsEmpty;
            }
        }

        public sealed override bool IsSynchronized
        {
            get
            {
                return this.mBasisSet.IsSynchronized;
            }
        }

        public sealed override object SyncRoot
        {
            get
            {
                return this.mBasisSet.SyncRoot;
            }
        }
    }
}

